namespace CRM_Perf_BenchMark
{
    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TestTools.WebTesting;
    using System.Net;
    using System.Text;
    using System.Xml;
    
    /// <summary>
    /// 1. Start at Sales homepage
    /// 2. Select Quotes 
    /// 3. Click New button
    /// 4. Enter Name
    /// 5. Select Potential Customer
    /// 6. Select Price List
    /// 7. Click Save
    /// 8. Click Existing product
    /// 9. Click New Quote Product button
    /// 10. Click Existing radio button
    /// 11.	Enter a Product
    /// 12.	Enter a Unit
    /// 13.	Enter a Quantity (1)
    /// 14.	Click Save and Close
    /// 15.	Click Save and Close
    /// </summary>

    public class CreateQuote : CrmWebTest
    {
        public void CreateQuote_PreWebTest(object sender, PreWebTestEventArgs e)
        {
			EntityRequest er = new EntityRequest();
			er.Type = EntityNames.Users;
			er.ReturnAs = EntityNames.Users;
			er.ParentID = EntityManager.Instance.OrgId;

			System.Collections.Hashtable Props = new System.Collections.Hashtable();

            if (e.WebTest.Context.ContainsKey("UserRole"))
            {
                Props.Add("role", e.WebTest.Context["UserRole"]);
            }
            
			EntityRequest AccountEr = new EntityRequest();
			AccountEr.Type = EntityNames.Accounts;
			AccountEr.ParentID = Guid.NewGuid();
			AccountEr.ReturnAs = EntityNames.Accounts;

			Props.Add(EntityNames.Accounts, new EntityRequest[] { AccountEr });

			er.Props = Props;

			System.Collections.Hashtable Entities = EntityManager.Instance.GetEntities(er);

			user = (CRMEntity)Entities[EntityNames.Users];
			account = (CRMEntity)Entities[EntityNames.Accounts];
            crmServer = user["CrmServer"];
            tokenKey = EntityManager.Instance.ReadTokenKey(user["organizationid"]);

            orgId = new Guid(user["organizationid"]);
          
            pricelevel = EntityManager.Instance.GetNextORGEntity(EntityNames.PriceLevels, new Guid(user["organizationid"]));

            er = new EntityRequest();
            er.Type = EntityNames.TransactionCurrency;
            er.ReturnAs = EntityNames.TransactionCurrency;
            er.ParentID = new Guid(user["organizationid"]);
            System.Collections.Hashtable currencies = EntityManager.Instance.GetEntities(er);
            currency = (CRMEntity)currencies[EntityNames.TransactionCurrency];

            e.WebTest.UserName = user["domainName"];
            e.WebTest.Password = user["userpassword"];
        }
      
        public void CreateQuote_PostWebTest(object sender, PostWebTestEventArgs e)
        {
            EntityManager.Instance.FreeEntity(user);
            EntityManager.Instance.FreeEntity(account);
            EntityManager.Instance.FreeEntity(pricelevel);
            EntityManager.Instance.FreeEntity(currency);
        }

		private void NewQuote_ValidateResponse(object sender, ValidationEventArgs e)
		{
			string ID = null;

			int idIdx = e.Response.BodyString.IndexOf(newIdMarker);
			ID = e.Response.BodyString.Substring(idIdx + (CreateQuote.newIdMarker.Length), 36);
			try
			{
				ID = new Guid(ID).ToString();
			}
			catch (System.FormatException fe)
			{
				System.Diagnostics.Trace.WriteLine("Format exception: " + fe.ToString());
				e.IsValid = false;
				return;
			}
			e.IsValid = true;
		}

        public CreateQuote()
        {
            WebRequest.RegisterPrefix("crm", new crmRequestFactory());
            gridXml = GridXmlHelper.QuotePageView(-1, myQuoteViewId, null);

            this.Proxy = null;            
            PreWebTest += new EventHandler<PreWebTestEventArgs>(CreateQuote_PreWebTest);
            PostWebTest += new EventHandler<PostWebTestEventArgs>(CreateQuote_PostWebTest);
        }

        public override IEnumerator<WebTestRequest> GetRequestEnumerator()
        {
			this.BeginTransaction("NavQuoteHomepage");

            _root_homepage_aspx hp = new _root_homepage_aspx(user);
            hp.etc = 1084;
            yield return (hp);

			this.EndTransaction("NavQuoteHomepage");			
			
			this.BeginTransaction("CreateQuote");

            sfa_quotes_edit_aspx dp = new sfa_quotes_edit_aspx(user);
            yield return (dp);

            referer = dp.lastResponse.ResponseUri.AbsoluteUri;

            _forms_FormScript_js_aspx f = new _forms_FormScript_js_aspx(user);
            f.etc = 1084;
            f.FormType = "main";
            f.FormName = "crmForm";
            headerItem = new WebTestRequestHeader("referer", referer);
            f.Headers.Add(headerItem);
            yield return (f);

            _controls_lookup_lookupsingle_aspx lookup = new _controls_lookup_lookupsingle_aspx(user);
            lookup.Class = "BasicCustomer";
            lookup.objecttypes = "1,2";
            lookup.browse = 0;
            lookup.ShowNewButton = 1;
            lookup.ShowPropButton = 1;
            lookup.DefaultType = 0;
            yield return (lookup);

            lookup = new _controls_lookup_lookupsingle_aspx(user);
            lookup.Class = "PriceLevelByCurrency";
            lookup.transactioncurrencyid = new Guid(currency["transactioncurrencyid"]);
            lookup.objecttypes = "1022";
            lookup.browse = 0;
            lookup.ShowNewButton = 1;
            lookup.ShowPropButton = 1;
            lookup.DefaultType = 0;
            yield return (lookup);

            // if the Help and Assistance pane is on and the user tabs through the fields of the Customer
            // detail pane, they'll hit this (heavy) request when the tab into the 
            // primay contact field.
            GetContextHtml_Helper.PrimaryCustomer(out ctxt, out ctxt_formXml, out ctxt_formSubmitId);
            
            if (ConfigSettings.Default.HelpAndAssistancePaneOn == "true")
            {
                RelatedInformation.RelatedInformation ri = new RelatedInformation.RelatedInformation();
                CrmRequest wtr = null;

                string formXml = ctxt_formXml;
                formXml = formXml.Replace("ACCOUNT_GUID", account["accountid"]);
                formXml = formXml.Replace("USER_GUID", user["systemuserid"]);
                try { ri.GetContextHtml(ctxt, formXml, ctxt_formSubmitId); }
                catch (crmException x)
                {
                    wtr = (CrmRequest)x.wtr;
                    wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                    string urlPath = wtr.Url.Remove(0, crmServer.Length);
                    urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                    rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                    headerItem = new WebTestRequestHeader();
                    headerItem.Name = "crmwrpctokentimestamp";
                    headerItem.Value = rpcInfo.timeStamp.ToString();
                    wtr.Headers.Add(headerItem);
                    headerItem = new WebTestRequestHeader();
                    headerItem.Name = "crmwrpctoken";
                    headerItem.Value = rpcInfo.token;
                    wtr.Headers.Add(headerItem);
                    wtr.Method = "Post";
                }
                yield return (wtr);
            }
            
            LookupService.LookupService serv = new LookupService.LookupService();
            CrmRequest lookupRequest = null;
            try
            {
                serv.RetrieveFormAssistantHtml("Category_Lookup", 1, "", "null", "BasicCustomer","");
            }
            catch (crmException x)
            {
                lookupRequest = (CrmRequest)x.wtr;
                lookupRequest.Url = Utils.ReplaceServerName(lookupRequest.Url, user);

                string urlPath = lookupRequest.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                lookupRequest.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                lookupRequest.Headers.Add(headerItem);
                lookupRequest.Method = "Post";                
            }
            yield return (lookupRequest);

            // if the Help and Assistance pane is on and the user tabs through the fields of the Pricelevel
            // detail pane, they'll hit this (heavy) request when the tab into the 
            // primay contact field.
            GetContextHtml_Helper.PrimaryPricelevel(out ctxt, out ctxt_formXml, out ctxt_formSubmitId);            
            if (ConfigSettings.Default.HelpAndAssistancePaneOn == "true")
            {
                RelatedInformation.RelatedInformation ri = new RelatedInformation.RelatedInformation();
                CrmRequest wtr = null;

                string formXml = ctxt_formXml;
                formXml = formXml.Replace("ACCOUNT_GUID", account["accountid"]);
                formXml = formXml.Replace("PRICELEVEL_GUID", pricelevel["pricelevelid"]);
                formXml = formXml.Replace("USER_GUID", user["systemuserid"]);
                try { ri.GetContextHtml(ctxt, formXml, ctxt_formSubmitId); }
                catch (crmException x)
                {
                    wtr = (CrmRequest)x.wtr;
                    wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                    string urlPath = wtr.Url.Remove(0, crmServer.Length);
                    urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                    rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                    headerItem = new WebTestRequestHeader();
                    headerItem.Name = "crmwrpctokentimestamp";
                    headerItem.Value = rpcInfo.timeStamp.ToString();
                    wtr.Headers.Add(headerItem);
                    headerItem = new WebTestRequestHeader();
                    headerItem.Name = "crmwrpctoken";
                    headerItem.Value = rpcInfo.token;
                    wtr.Headers.Add(headerItem);
                    wtr.Method = "Post";
                }
                yield return (wtr);
            }

            serv = new LookupService.LookupService();
            lookupRequest = null;
            try
            {
                serv.RetrieveFormAssistantHtml("Category_Lookup", 1022, "", "&#38;transactioncurrencyid&#61;&#37" + "{" + currency[EntityIDNames.TransactionCurrency] + "}", "PricelevelByCurrency", "");
            }
            catch (crmException x)
            {
                lookupRequest = (CrmRequest)x.wtr;
                lookupRequest.Url = Utils.ReplaceServerName(lookupRequest.Url, user);

                string urlPath = lookupRequest.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                lookupRequest.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                lookupRequest.Headers.Add(headerItem);
                lookupRequest.Method = "Post";
            }
            yield return (lookupRequest);

            dp = new sfa_quotes_edit_aspx(user);            
            dp.crmFormSubmitXml = EntityXmlHelper.GetCreateQuoteXml(new Guid(user["systemuserid"]), 8, new Guid(pricelevel["pricelevelid"]), 1022, new Guid(account["accountid"]),1); // q.Serialize();

            rpcInfo = Utils.GenerateWRPCToken(sfa_quotes_edit_aspx.url, user, tokenKey);
            dp.CRMWRPCToken = rpcInfo.token;
            dp.CRMWRPCTokenTimeStamp = rpcInfo.timeStamp;
            dp.crmFormSubmitMode = 1;
            dp.crmFormUserModified = true;
            dp.crmFormSubmitObjectType = 1084;
            dp.crmFormSubmitSecurity = 852023;
            dp.crmFormSubmitOnline = 1;
			dp.ValidateResponse += this.NewQuote_ValidateResponse;
            yield return (dp);

            
            //get the newly created Quote id out of the post reply
            int idIdx = dp.lastResponse.BodyString.IndexOf(newIdMarker);
            string tempNewQuoteId = dp.lastResponse.BodyString.Substring(idIdx + (CreateQuote.newIdMarker.Length), 36);
			newQuoteId = new Guid(tempNewQuoteId).ToString();

            // last request to this page was a post, this is a fetch, so make a new object since
            // the existing dp is setup to post, and this is a get.
            dp = new sfa_quotes_edit_aspx(user);
            dp.id = new Guid(newQuoteId);
            yield return (dp);

            referer = dp.lastResponse.ResponseUri.AbsoluteUri;

            AppGridWebService.AppGridWebService agws = new AppGridWebService.AppGridWebService();
            WebTestRequest wtrRefresh = null;
            try { agws.Refresh(gridXml); }
            catch (crmException x)
            {
                wtrRefresh = x.wtr;
                wtrRefresh.Url = Utils.ReplaceServerName(wtrRefresh.Url, user);

                string urlPath = wtrRefresh.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtrRefresh.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtrRefresh.Headers.Add(headerItem);
                wtrRefresh.Method = "Post";
            }
            yield return (wtrRefresh);


            f = new _forms_FormScript_js_aspx(user);
            f.etc = 1084;
            f.FormType = "main";
            f.FormName = "crmForm";
            headerItem = new WebTestRequestHeader("referer", referer);
            f.Headers.Add(headerItem);
            yield return (f);

            this.EndTransaction("CreateQuote");

            gridXml1 = GridXmlHelper.QuoteDetailPageRefresh(-1, quoteDetailViewId, newQuoteId, null);
 
            this.BeginTransaction("CreateQuoteDetail");
                        
            sfa_quotes_areas_aspx qa = new sfa_quotes_areas_aspx(user);
            qa.oId = new Guid(newQuoteId);
            qa.oType = 1084;
            qa.security = 852023;
            qa.tabSet = "areaExistingProducts";
            yield return (qa);

            sfa_quotedetail_edit_aspx qdCreate = new sfa_quotedetail_edit_aspx(user);
            qdCreate._CreateFromType = 1084;
            qdCreate._CreateFromId = new Guid(newQuoteId);
            qdCreate.isproductoverridden = 1;
            yield return (qdCreate);

            referer = qdCreate.lastResponse.ResponseUri.AbsoluteUri;

            f = new _forms_FormScript_js_aspx(user);
            f.etc = 1085;
            f.FormType = "main";
            f.FormName = "crmForm";
            headerItem = new WebTestRequestHeader("referer", referer);
            f.Headers.Add(headerItem);
            yield return (f);

            lookup = new _controls_lookup_lookupsingle_aspx(user);
            lookup.Class = "ProductWithPriceLevel";
            lookup.objecttypes = "1024";
            lookup.browse = 0;
            lookup.ShowNewButton = 1;
            lookup.ShowPropButton = 1;
            lookup.DefaultType = 0;
            yield return (lookup);

            idIdx = lookup.lastResponse.BodyString.IndexOf(prodIdMarker);
            string tempProductId = lookup.lastResponse.BodyString.Substring(idIdx + (CreateQuote.prodIdMarker.Length), 36);
            ProductId = new Guid(tempProductId);

            lookup = new _controls_lookup_lookupsingle_aspx(user);
            lookup.Class = "Unit";
            lookup.objecttypes = "1055";
            lookup.ObjectId = new Guid(newQuoteId);
            lookup.ProductId = ProductId;
            lookup.ObjectTypeCode = 1084;
            lookup.browse = 1;
            lookup.ShowNewButton = 0;
            lookup.ShowPropButton = 1;
            lookup.DefaultType = 0;
            yield return (lookup);

            idIdx = lookup.lastResponse.BodyString.IndexOf(unitIdMarker);
            string tempUOMId = lookup.lastResponse.BodyString.Substring(idIdx + (CreateQuote.unitIdMarker.Length), 36);
            UOMId = new Guid(tempUOMId);

            sfa_quotes_cmd_getquantitydecimal_aspx getQuantityDec = new sfa_quotes_cmd_getquantitydecimal_aspx(user);
            getQuantityDec.objectTypeCode = 1084;
            getQuantityDec.objectId = new Guid(newQuoteId);
            getQuantityDec.productId = ProductId;
            getQuantityDec.uomId = UOMId;
            // This is a post but there are no formbody parameters so have to create formposthttpbody and keep it empty
            getQuantityDec.Method = "POST";
            FormPostHttpBody formBody = new FormPostHttpBody();
            getQuantityDec.Body = formBody;

            yield return (getQuantityDec);

            _controls_number_formatNumber_xsl format = new _controls_number_formatNumber_xsl(crmServer);
            yield return (format);

            qdCreate = new sfa_quotedetail_edit_aspx(user);            
            // QueryStrings
            qdCreate._CreateFromId = new Guid(newQuoteId);
            qdCreate._CreateFromType = 1084;

            //FormSubmits
            qdCreate.crmFormSubmitMode = 1;
            qdCreate.crmFormUserModified = true;
            qdCreate.crmFormSubmitObjectType = 1085;
            qdCreate.crmFormSubmitSecurity = 852023;
            qdCreate.crmFormSubmitOnline = 1;
            qdCreate.isproductoverridden = 1;
            
            rpcInfo = Utils.GenerateWRPCToken(sfa_quotedetail_edit_aspx.url, user, tokenKey);
            qdCreate.CRMWRPCToken = rpcInfo.token;
            qdCreate.CRMWRPCTokenTimeStamp = rpcInfo.timeStamp;
            qdCreate.crmFormSubmitXml = EntityXmlHelper.GetCreateQuoteDetailXml(new Guid(newQuoteId), int.Parse(Utils.GetRandomNumber(10, 15)), int.Parse(Utils.GetRandomNumber(10, 20)));
            yield return (qdCreate);

            agws = new AppGridWebService.AppGridWebService();
            wtrRefresh = null;
            try { agws.Refresh(gridXml1); }
            catch (crmException x)
            {
                wtrRefresh = x.wtr;
                wtrRefresh.Url = Utils.ReplaceServerName(wtrRefresh.Url, user);
                string urlPath = wtrRefresh.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtrRefresh.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtrRefresh.Headers.Add(headerItem);
                wtrRefresh.Method = "Post";
            }
            yield return (wtrRefresh);

            this.EndTransaction("CreateQuoteDetail");
        }

        private static RelatedInformation.Context ctxt;
        private static string ctxt_formXml;
        private static string ctxt_formSubmitId;

        private const string newIdMarker = @"separator + ""id=";
        private const string prodIdMarker = @"><tr class=""ms-crm-List-Row"" oid=""&#123;";
        private const string unitIdMarker = @"><tr class=""ms-crm-List-Row"" oid=""&#123;";
        private string gridXml;
        private string gridXml1;
        private static string myQuoteViewId = "008FBB15-98E9-4C5D-A81A-E685FF8CCC2C";
        private static string quoteDetailViewId = "4EC5BD8A-5580-49AA-BD6E-1368AD611B6A";
        private CRMEntity user;
        private CRMEntity currency;
        private string newQuoteId;        
        private CRMEntity account;
        private CRMEntity pricelevel;
        private string crmServer;
        private string tokenKey;

        private Guid orgId;
        private Guid ProductId;
        private Guid UOMId;

        private string referer;
        private WRPCInfo rpcInfo;
        private WebTestRequestHeader headerItem;
    }
}